#include "Game.hpp"

Game::Game()
{
    pCamera = new Camera();

    inCaptureMode = true;

    mouseRightButtonDown = false;
    mouseLeftButtonDown = false;
    shiftDown = false;

    //worldInterface = Interface::getInstance();;

    App::I().MouseMode(App::Free);

    // TESTING
    mi::Win *test = new mi::Win("Hello World!");

    test->GetMainView().AddWidget(
        new mi::Textbox("Welcome, victorious solider. \nYet not unscarred. The world is your oyster - free to explore"
                         "Free to destroy...\n\nIt has been many years since we have had the honor of serving a boonborn," 
                         "and I fear we shall not live long enough to see the line of succession reach its end. \n\n"
                         "We are the princes of your multiverse, yey, though i walk through the valley of the shadow of darth.\n"
                         "Free to destroy...\n\nIt has been many years since we have had the honor of serving a boonborn," 
                         "and I fear we shall not live long enough to see the line of succession reach its end. \n\n"
                         "We are the princes of your multiverse, yey, though i walk through the valley of the shadow of darth.\n"
                         "Free to destroy...\n\nIt has been many years since we have had the honor of serving a boonborn," 
                         "and I fear we shall not live long enough to see the line of succession reach its end. \n\n"
                         "We are the princes of your multiverse, yey, though i walk through the valley of the shadow of darth.\n"
                         "The world shall see no evil, only good tear it self apart from the inside.\n\n"
                         "I am no one. Leave. -- milcho"));

    mi::Interface::I().AddWidget(test);

    //  add second window

    test = new mi::Win("Hello Too!");
    
    mi::View *tv1 = new mi::View(mi::Vertical);
    (*tv1).AddWidget(new mi::Button("one")).AddWidget(new mi::Button("two")).AddWidget(new mi::Button("three"));
    
    mi::View *tv2 = new mi::View(mi::Vertical);
    (*tv2).AddWidget(new mi::Button("four")).AddWidget(new mi::Button("five")).AddWidget(new mi::Button("six"));

    test->AddHorizontalView(3).AddWidget(tv1).AddWidget(tv2);

    test->AddHorizontalView(1).AddWidget(new mi::Button("now")).
                              AddWidget(new mi::Button("what?"));
    mi::Interface::I().AddWidget(test);

    mi::CycleButton *tCB = new mi::CycleButton();
    tCB->AddOption("One");
    tCB->AddOption("Two");
    tCB->AddOption("Three");

    mi::Win *third = new mi::Win("Third Test");
    third->SetSize(Vec2i(400,20));
    third->GetMainView().AddWidget(tCB);

    mi::Interface::I().AddWidget(third);

    App::I().ClearColor(Vec3d(0.5, 0.5, 0.5));
}


Game::~Game()
{

}

void Game::Init()
{
    pCamera->SetMovementSpeed(3);

    ShaderObject::InitDefaultShaders();

    /*
    backgroundMusic = new sf::Music();
    
    if (!backgroundMusic->OpenFromFile("resources/music/mainmusic.ogg"))
    {
        std::cout << "Error opening background music!\n";
    }
    else
    {
        backgroundMusic->SetVolume(volumeLevel);
        backgroundMusic->SetLoop(true);
    }
    */

}

void Game::Resize(int w, int h)
{

}

void Game::Draw()
{
    PlaceCamera();

//    w_skyDome->Draw(mainPlayer->GetDirection());

//    Planet::GetInstance()->Draw();

    RenderScene();

//	GameObjectManager::GetInstance()->Draw();

//	DebugDrawManager::GetInstance()->Draw();
}

void Game::Draw2d()
{
//	ShaderObject::GetBaseShader()->Enable();

//    // put camera coordinates on screen
//    Vec3d camPos = pCamera->GetPosition();
//    double cx = ((int)(camPos.x*100.0))/100.0;
//    double cy = ((int)(camPos.y*100.0))/100.0;
//    double cz = ((int)(camPos.z*100.0))/100.0;

//    Vec3d rayDirection = pCamera->GetLookAtDirection();

//    // Draw crosshair in the middle of viewport
//    int midX = Window::GetDimentions().x/2;
//    int midY = Window::GetDimentions().y/2;
//    glBegin(GL_LINES);
//    glVertex2d(midX-10.0, midY);
//    glVertex2d(midX+10.0, midY);
//    glVertex2d(midX, midY-10.0);
//    glVertex2d(midX, midY+10.0);
//    glEnd();

//	ShaderObject::GetBaseShader()->Enable();
//    StatsManager::GetInstance()->Draw();
//    DatablockAnalyzer *dba = DatablockAnalyzer::GetInstance();
}

void Game::RenderScene()
{    // this draws all objects in the scene (NOT the skybox)
    // it doesn't place a camera, it assumes the camera is already placed
}

void Game::PlaceCamera()
{
    pCamera->Place();
}

void Game::MouseClick(sf::Mouse::Button button, sf::MouseState state, int x, int y)
{
    if (button == sf::Mouse::Right) 
    {
        mouseRightButtonDown = !mouseRightButtonDown;
    }
    if (button == sf::Mouse::Left)
    {
        mouseLeftButtonDown = !mouseLeftButtonDown;
    }
    // Pass event to player
    //mainPlayer->MouseClick(button, state, x, y);
}

void Game::MouseMoved(int x, int y, int dx, int dy)
{
  if (App::I().MouseMode() == App::Capture)
  {

  }
}

void Game::MouseDragged(int x, int y, int dx, int dy)
{
    if (App::I().MouseMode() == App::Capture)
    {

    }
}

void Game::MouseWheel(int dir)
{

}

void Game::KeysDown(sf::Event::KeyEvent key)
{
  switch (key.code)
  {
    case sf::Keyboard::PageDown :

    break;
    case sf::Keyboard::PageUp :

    break;
    case sf::Keyboard::LShift :
      shiftDown = true;
    break;
    case sf::Keyboard::F4 :

    break;
    case sf::Keyboard::F :
      /*
      if (App::I().MouseMode() == App::Free)
        App::I().MouseMode(App::Capture);
      else
        App::I().MouseMode(App::Free);
      */
    break;
    case sf::Keyboard::Escape :
      App::I().Exit();
    break;
  }
}

void Game::KeysUp(sf::Event::KeyEvent key)
{
    switch (key.code) 
    {
        case sf::Keyboard::LShift :
            shiftDown = false;
        break;
        case sf::Keyboard::PageDown :
        break;            
        case sf::Keyboard::PageUp :

        break;
    }     
}

void Game::TextEntered(char ch)
{
  // todo...
}

void Game::FocusChanged(bool gained)
{
    //EventManager::OnFocusChange(gained);
    if(!gained)
        inCaptureMode = App::Free;
}


void Game::ShowMainMenu()
{
    //worldInterface->showMenu();
}

void Game::Update(double dTime)
{
//    GLIDManager::Update(dTime);
//    if (mainTerrain->isItInitialized())
//    {    // main terrain has been Inited, hide loading screen
//        worldInterface->showLoadingScreen(false);
//    }
//    if (worldInterface->Update(dTime))
//    { // this only returns true if the main menu or loading screen
//        Window::MouseMode(Window::Free);    // always free mouse in main menu mode
//        return;
//    }
//    if (inCaptureMode)
//    {
//        Window::MouseMode(Window::Capture);
//    }
//    else
//    {
//        Window::MouseMode(Window::Free);
//    }

//	// Update loop on game objects
//	GameObjectManager::GetInstance()->Update(dTime);

//    pCamera->Update(dTime);
//    mainTerrain->Update(dTime);
//    mainPlayer->Update(dTime);
//    Planet::GetInstance()->update(dTime);

//    // sync the player pos
//    playerPos->x = mainPlayer->GetPosition().x;
//    playerPos->y = mainPlayer->GetPosition().y;
//    playerPos->z = mainPlayer->GetPosition().z;
}

bool Game::DrawSkybox()
{
    Vec3d camPos = pCamera->GetPosition();
    double cam_x = camPos.x;
    double cam_y = camPos.y;
    double cam_z = camPos.z;

    glPushMatrix();
    //glLoadIdentity();
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);

    // First apply scale matrix,
    // then translate
    glTranslated(cam_x, cam_y, cam_z);
    glScalef(5,5,5);
    

    float offset = 0.001f;
    float cz = 0.0f + offset,cx = 1.0f-offset;
    float r = 1.0f; // If you have border issues change this to 1.005f
    // Common Axis Y - FRONT Side

    GLdouble up[3] = {0.5, 0.8, 0.92};
//    GLdouble dn[3] = {0.01, 0.01, 0.02};
    GLdouble dn[3] = {0.5, 0.8, 0.92};



    glBegin(GL_QUADS);    
        glColor3dv(up);
        glVertex3d( r, 1.0f,-r);
        glVertex3d( r, 1.0f, r);
        glVertex3d(-r, 1.0f, r); 
        glVertex3d(-r, 1.0f,-r);
    //glEnd();
 
    // Common Axis Y - BACK side

    //glBegin(GL_QUADS);        
        glColor3dv(dn);
        glVertex3d(-r,-1.0f,-r);
        glVertex3d(-r,-1.0f, r);
        glVertex3d( r,-1.0f, r); 
        glVertex3d( r,-1.0f,-r);
    //glEnd();
 
    // Common Axis X - Left side

    //glBegin(GL_QUADS);        
        glColor3dv(up);
        glVertex3d(-1.0f,  r, r);    
        glColor3dv(dn);
        glVertex3d(-1.0f, -r, r); 
        glVertex3d(-1.0f, -r,-r);
        glColor3dv(up);
        glVertex3d(-1.0f,  r,-r);        
    //glEnd();

    // Common Axis X - Right side

    //glBegin(GL_QUADS);        
        glColor3dv(dn);
        glVertex3d(1.0f, -r, r);
        glColor3dv(up);
        glVertex3d(1.0f,  r, r); 
        glVertex3d(1.0f,  r,-r);
        glColor3dv(dn);
        glVertex3d(1.0f, -r,-r);
    //glEnd();

    // Common Axis Z - Draw Up side
    //glBegin(GL_QUADS);        
        glColor3dv(up);
        glVertex3d( r,  r,1.0f);
        glColor3dv(dn);
        glVertex3d( r, -r,1.0f); 
        glVertex3d(-r, -r,1.0f);
        glColor3dv(up);
        glVertex3d(-r,  r,1.0f);
    //glEnd();

    // Common Axis Z - Down side
    //glBegin(GL_QUADS);        
        glColor3dv(dn);
        glTexCoord2f(cz,cx); glVertex3d( r, -r,-1.0f);
        glColor3dv(up);
        glTexCoord2f(cz,cz); glVertex3d( r,  r,-1.0f); 
        glTexCoord2f(cx,cz); glVertex3d(-r,  r,-1.0f);
        glColor3dv(dn);
        glTexCoord2f(cx,cx); glVertex3d(-r, -r,-1.0f);
    glEnd();

    // Load Saved Matrix
    /*pCamera->moveTo(cam_x,cam_y,cam_z,pCamera->getHorAng(), pCamera->getVerAng());
    gluLookAt(
        cam_x,cam_y,cam_z,
        pCamera->getLookAtx(),pCamera->getLookAty(),pCamera->getLookAtz(),
        0,1,0);*/
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glPopMatrix();
    return true;
}
